﻿using FileService.Domain;
using Microsoft.Extensions.Options;
using Minio;
using Minio.DataModel.Args;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FileService.infrastructure.Services
{
    public class MinioStorageClient : IStorageClient
    {
        private IOptionsSnapshot<MinioStorageOptions> options;

        public MinioStorageClient(IOptionsSnapshot<MinioStorageOptions> options)
        {
            this.options = options;
        }

        public StorageType StorageType => StorageType.Public;

        static string ConcatUrl(params string[] segments)
        {
            for (int i = 0; i < segments.Length; i++)
            {
                string s = segments[i];
                if (s.Contains(".."))
                {
                    throw new ArgumentException("路径中不能含有..");
                }
                segments[i] = s.Trim('/');//把开头结尾的/去掉
            }
            return string.Join('/', segments);
        }

        public async Task<string> SaveAsync(string key, Stream content, CancellationToken cancellationToken = default)
        {
            if (key.StartsWith('/'))
            {
                throw new ArgumentException("key 不能以/开头", nameof(key));
            }
            // byte[] bytes = content.ToArray();
            if (content.Length <= 0)
            {
                throw new ArgumentException("file 不能为空", nameof(content));
            }

            string bucketName = options.Value.BucketName;
            string endpoint = options.Value.Endpoint;
            string accessKey = options.Value.AccessKey;
            string secretKey = options.Value.SecretKey;

            string fileName = key;

            using var minio = new MinioClient()
            .WithEndpoint(endpoint)
            .WithCredentials(accessKey, secretKey)
           .Build();
            PutObjectArgs args = new PutObjectArgs().WithBucket(bucketName)
                .WithObject(fileName)
                .WithStreamData(content)
                .WithObjectSize(content.Length)
                .WithContentType("application/octet-stream");
            //   .WithContentType("application/zip");
            var a = await minio.PutObjectAsync(args, cancellationToken);
            //  await minio.PutObjectAsync(bucketName, objectName, fileName, contentType: "application/octet-stream");
            if (a != null)
            {
                return fileName;
            }
            else
            {
                throw new ArgumentException("上传失败！");
            }

            //  throw new NotImplementedException();
        }
    }
}
